///************************************************************************
/// <copyrigth>2018-2019 Corporation.All Rights Reserved</copyrigth>
/// <author>tangyingzhong</author>
/// <contact>tangyz114987@outlook.com</contact>
/// <version>v1.0.0</version>
/// <describe>
/// It is prepared for the logger so that you can easily use log
///</describe>
/// <date>2019/8/1</date>
///***********************************************************************
#ifndef SYSTEMLOG_H
#define SYSTEMLOG_H

#include <iostream>
#include "Common/CommonTool.h"
#include "Log.h"

using namespace SystemTool;

extern SystemTool::IO::Log* pSystemLogger;

#define LOG(LogType,FileName,LineNo,FunctionName,Message,Remark) \
pSystemLogger->Record(LogType, \
CommonTool::GetCurProcessId(), \
CommonTool::GetCurThreadID(), \
FileName,\
LineNo, \
FunctionName, \
Message,\
Remark); 

#define LOG_TRACE(LogType,FileName,LineNo,FunctionName,Message,Remark) \
pSystemLogger->Trace(LogType, \
CommonTool::GetCurProcessId(), \
CommonTool::GetCurThreadID(), \
FileName,\
LineNo, \
FunctionName, \
Message,\
Remark); 

#define LOG_STD(Message) \
{\
	std::cout << Message << std::endl;\
}

#define SET_MAX_LOG_SIZE(iSize) pSystemLogger->SetMaxLoggerSize(iSize);

#define SET_HOW_MUCH_RECORD_TO_FILE_ONE_TIME(iCount) pSystemLogger->SetLogCountOneTime(iCount);

#define LOG_FLUSH() pSystemLogger->Flush();

#define LOG_DEBUG(Message,Remark) \
LOG(SystemTool::IO::LOG_TYPE_ENUM::LOG_DEBUG,_FILE_,__LINE__,_FUNCNAME_,Message,Remark) \
LOG_TRACE(SystemTool::IO::LOG_TYPE_ENUM::LOG_DEBUG,_FILE_,__LINE__,_FUNCNAME_,Message,Remark) \
LOG_STD(Message)

#define LOG_ERROR(Message,Remark) \
LOG(SystemTool::IO::LOG_TYPE_ENUM::LOG_ERROR,_FILE_,__LINE__,_FUNCNAME_,Message,Remark) \
LOG_TRACE(SystemTool::IO::LOG_TYPE_ENUM::LOG_ERROR,_FILE_,__LINE__,_FUNCNAME_,Message,Remark) \
LOG_STD(Message)

#define LOG_WARN(Message,Remark) \
LOG(SystemTool::IO::LOG_TYPE_ENUM::LOG_WARN, _FILE_, __LINE__, _FUNCNAME_, Message, Remark) \
LOG_TRACE(SystemTool::IO::LOG_TYPE_ENUM::LOG_WARN, _FILE_, __LINE__, _FUNCNAME_, Message, Remark) \
LOG_STD(Message)

#define LOG_INFO(Message,Remark) \
LOG(SystemTool::IO::LOG_TYPE_ENUM::LOG_INFOR,_FILE_,__LINE__,_FUNCNAME_,Message,Remark) \
LOG_TRACE(SystemTool::IO::LOG_TYPE_ENUM::LOG_INFOR,_FILE_,__LINE__,_FUNCNAME_,Message,Remark) \
LOG_STD(Message)

#define LOG_DEBUG_EX(Message) \
{\
std::string strRemarkData = "No remark info"; \
LOG(SystemTool::IO::LOG_TYPE_ENUM::LOG_DEBUG, _FILE_, __LINE__, _FUNCNAME_, Message, strRemarkData) \
LOG_TRACE(SystemTool::IO::LOG_TYPE_ENUM::LOG_DEBUG, _FILE_, __LINE__, _FUNCNAME_, Message, strRemarkData) \
LOG_STD(Message)\
}

#define LOG_ERROR_EX(Message) \
{\
std::string strRemarkData = "No remark info"; \
LOG(SystemTool::IO::LOG_TYPE_ENUM::LOG_ERROR,_FILE_,__LINE__,_FUNCNAME_,Message,strRemarkData) \
LOG_TRACE(SystemTool::IO::LOG_TYPE_ENUM::LOG_ERROR,_FILE_,__LINE__,_FUNCNAME_,Message,strRemarkData) \
LOG_STD(Message)\
}

#define LOG_WARN_EX(Message) \
{\
std::string strRemarkData = "No remark info"; \
LOG(SystemTool::IO::LOG_TYPE_ENUM::LOG_WARN, _FILE_, __LINE__, _FUNCNAME_, Message, strRemarkData) \
LOG_TRACE(SystemTool::IO::LOG_TYPE_ENUM::LOG_WARN, _FILE_, __LINE__, _FUNCNAME_, Message, strRemarkData) \
LOG_STD(Message)\
}

#define LOG_INFO_EX(Message) \
{\
std::string strRemarkData = "No remark info"; \
LOG(SystemTool::IO::LOG_TYPE_ENUM::LOG_INFOR,_FILE_,__LINE__,_FUNCNAME_,Message,strRemarkData) \
LOG_TRACE(SystemTool::IO::LOG_TYPE_ENUM::LOG_INFOR,_FILE_,__LINE__,_FUNCNAME_,Message,strRemarkData) \
LOG_STD(Message)\
}

class AutoLogger
{
public:
	AutoLogger(std::string strFileName,
		int iLineNo, 
		std::string strFunctionName,
		std::string strStartMessage,
		std::string strEndMessage) :m_strFileName(strFileName),
		m_iLineNo(iLineNo),
		m_strFunctionName(strFunctionName),
		m_strStartMessage(strStartMessage),
		m_strEndMessage(strEndMessage)
	{
		LOG(SystemTool::IO::LOG_TYPE_ENUM::LOG_DEBUG,
			m_strFileName, 
			m_iLineNo, 
			m_strFunctionName, 
			m_strStartMessage, 
			"");

		LOG_TRACE(SystemTool::IO::LOG_TYPE_ENUM::LOG_DEBUG,
			m_strFileName, 
			m_iLineNo,
			m_strFunctionName,
			m_strStartMessage,
			"");
	}

	~AutoLogger()
	{
		LOG(SystemTool::IO::LOG_TYPE_ENUM::LOG_DEBUG,
			m_strFileName, 
			m_iLineNo, 
			m_strFunctionName, 
			m_strEndMessage,
			"");

		LOG_TRACE(SystemTool::IO::LOG_TYPE_ENUM::LOG_DEBUG,
			m_strFileName, 
			m_iLineNo, 
			m_strFunctionName, 
			m_strEndMessage,
			"");
	}

private:
	std::string m_strFileName;

	int m_iLineNo;

	std::string m_strFunctionName;

	std::string m_strStartMessage;

	std::string m_strEndMessage;
};

#define LOG_BEGIN() \
std::string strStartMessage = std::string("-----------------Start Function : ") + _FUNCNAME_ + std::string("-----------------");\
\
std::string strEndMessage = std::string("-----------------End Function : ") + _FUNCNAME_ + std::string("-----------------");\
\
AutoLogger Logger(_FILE_,__LINE__,_FUNCNAME_,strStartMessage,strEndMessage);

#define LOG_START(strMesage) \
std::string strStartMessage = std::string("-----------------Start Function : ") + strMesage + std::string("-----------------");\
\
std::string strEndMessage = std::string("-----------------End Function : ") + strMesage + std::string("-----------------");\
\
AutoLogger Logger(_FILE_,__LINE__,_FUNCNAME_,strStartMessage,strEndMessage);

#endif // SYSTEMLOG_H
